"use client"

import { useState, useCallback } from "react"
import { useDropzone } from "react-dropzone"
import { cn } from "@/lib/utils"
import { Button } from "@/components/ui/button"
import { Progress } from "@/components/ui/progress"
import { Card, CardContent } from "@/components/ui/card"
import { Badge } from "@/components/ui/badge"
import {
  Upload,
  File,
  Image as ImageIcon,
  X,
  FileText,
  Download,
  Eye
} from "lucide-react"

interface FileUploadProps {
  onFilesChange?: (files: File[]) => void
  accept?: string
  multiple?: boolean
  maxSize?: number // in MB
  className?: string
  placeholder?: string
  showPreview?: boolean
  allowedTypes?: string[]
}

interface UploadedFile {
  file: File
  id: string
  preview?: string
  progress: number
  status: 'uploading' | 'completed' | 'error'
  error?: string
}

export function FileUpload({
  onFilesChange,
  accept = "image/*,.pdf,.doc,.docx,.xls,.xlsx,.ppt,.pptx,.txt",
  multiple = true,
  maxSize = 10,
  className,
  placeholder = "拖拽文件到此处或点击上传",
  showPreview = true,
  allowedTypes
}: FileUploadProps) {
  const [files, setFiles] = useState<UploadedFile[]>([])
  const [isDragActive, setIsDragActive] = useState(false)

  const onDrop = useCallback((acceptedFiles: File[], rejectedFiles: any[]) => {
    setIsDragActive(false)
    
    // 处理被拒绝的文件
    rejectedFiles.forEach(rejection => {
      console.error('文件被拒绝:', rejection.errors)
    })

    // 处理接受的文件
    const newFiles = acceptedFiles.map(file => {
      const uploadedFile: UploadedFile = {
        file,
        id: Math.random().toString(36).substr(2, 9),
        progress: 0,
        status: 'uploading'
      }

      // 如果是图片，生成预览
      if (showPreview && file.type.startsWith('image/')) {
        const reader = new FileReader()
        reader.onload = (e) => {
          setFiles(prev => prev.map(f => 
            f.id === uploadedFile.id 
              ? { ...f, preview: e.target?.result as string }
              : f
          ))
        }
        reader.readAsDataURL(file)
      }

      return uploadedFile
    })

    setFiles(prev => [...prev, ...newFiles])
    
    // 模拟上传进度
    newFiles.forEach(uploadedFile => {
      simulateUpload(uploadedFile.id)
    })

    if (onFilesChange) {
      onFilesChange([...files, ...newFiles].map(f => f.file))
    }
  }, [files, onFilesChange, showPreview])

  const simulateUpload = (fileId: string) => {
    let progress = 0
    const interval = setInterval(() => {
      progress += Math.random() * 30
      if (progress >= 100) {
        progress = 100
        clearInterval(interval)
        setFiles(prev => prev.map(f => 
          f.id === fileId 
            ? { ...f, progress: 100, status: 'completed' }
            : f
        ))
      } else {
        setFiles(prev => prev.map(f => 
          f.id === fileId 
            ? { ...f, progress }
            : f
        ))
      }
    }, 200)
  }

  const removeFile = (fileId: string) => {
    setFiles(prev => prev.filter(f => f.id !== fileId))
    if (onFilesChange) {
      onFilesChange(files.filter(f => f.id !== fileId).map(f => f.file))
    }
  }

  const getFileIcon = (file: File) => {
    if (file.type.startsWith('image/')) {
      return <ImageIcon className="h-4 w-4" />
    } else if (file.type.includes('pdf')) {
      return <FileText className="h-4 w-4" />
    } else {
      return <File className="h-4 w-4" />
    }
  }

  const formatFileSize = (bytes: number) => {
    if (bytes === 0) return '0 Bytes'
    const k = 1024
    const sizes = ['Bytes', 'KB', 'MB', 'GB']
    const i = Math.floor(Math.log(bytes) / Math.log(k))
    return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i]
  }

  const { getRootProps, getInputProps, isDragReject } = useDropzone({
    onDrop,
    accept: allowedTypes ? 
      Object.fromEntries(allowedTypes.map(type => [type, []])) :
      accept.split(',').reduce((acc, type) => {
        const trimmedType = type.trim()
        if (trimmedType.startsWith('.')) {
          acc[trimmedType] = []
        } else if (trimmedType.includes('/')) {
          acc[trimmedType] = []
        }
        return acc
      }, {} as Record<string, []>),
    multiple,
    maxSize: maxSize * 1024 * 1024,
    onDragEnter: () => setIsDragActive(true),
    onDragLeave: () => setIsDragActive(false)
  })

  return (
    <div className={cn("space-y-4", className)}>
      <Card className={cn(
        "border-2 border-dashed transition-colors",
        isDragActive && !isDragReject && "border-blue-500 bg-blue-50",
        isDragReject && "border-red-500 bg-red-50",
        !isDragActive && "border-gray-300 hover:border-gray-400"
      )}>
        <CardContent className="p-6">
          <div
            {...getRootProps()}
            className="cursor-pointer text-center"
          >
            <input {...getInputProps()} />
            <Upload className="h-12 w-12 mx-auto mb-4 text-gray-400" />
            <p className="text-lg font-medium mb-2">{placeholder}</p>
            <p className="text-sm text-gray-500 mb-4">
              支持格式: {accept} | 最大大小: {maxSize}MB
            </p>
            <Button variant="outline" type="button">
              选择文件
            </Button>
          </div>
        </CardContent>
      </Card>

      {/* 文件列表 */}
      {files.length > 0 && (
        <div className="space-y-2">
          <h4 className="text-sm font-medium">已上传文件 ({files.length})</h4>
          <div className="space-y-2">
            {files.map((uploadedFile) => (
              <Card key={uploadedFile.id} className="p-3">
                <div className="flex items-center justify-between">
                  <div className="flex items-center space-x-3 flex-1">
                    {uploadedFile.preview ? (
                      <img
                        src={uploadedFile.preview}
                        alt={uploadedFile.file.name}
                        className="h-10 w-10 object-cover rounded"
                      />
                    ) : (
                      <div className="h-10 w-10 bg-gray-100 rounded flex items-center justify-center">
                        {getFileIcon(uploadedFile.file)}
                      </div>
                    )}
                    
                    <div className="flex-1 min-w-0">
                      <p className="text-sm font-medium truncate">
                        {uploadedFile.file.name}
                      </p>
                      <p className="text-xs text-gray-500">
                        {formatFileSize(uploadedFile.file.size)}
                      </p>
                      
                      {uploadedFile.status === 'uploading' && (
                        <div className="mt-1">
                          <Progress value={uploadedFile.progress} className="h-1" />
                          <p className="text-xs text-gray-500 mt-1">
                            上传中... {Math.round(uploadedFile.progress)}%
                          </p>
                        </div>
                      )}
                      
                      {uploadedFile.status === 'error' && (
                        <p className="text-xs text-red-500 mt-1">
                          {uploadedFile.error || '上传失败'}
                        </p>
                      )}
                    </div>
                    
                    <div className="flex items-center space-x-2">
                      <Badge variant={
                        uploadedFile.status === 'completed' ? 'default' :
                        uploadedFile.status === 'uploading' ? 'secondary' :
                        'destructive'
                      }>
                        {uploadedFile.status === 'completed' ? '已完成' :
                         uploadedFile.status === 'uploading' ? '上传中' :
                         '失败'}
                      </Badge>
                      
                      {uploadedFile.status === 'completed' && (
                        <>
                          <Button
                            variant="ghost"
                            size="sm"
                            className="h-8 w-8 p-0"
                          >
                            <Eye className="h-4 w-4" />
                          </Button>
                          <Button
                            variant="ghost"
                            size="sm"
                            className="h-8 w-8 p-0"
                          >
                            <Download className="h-4 w-4" />
                          </Button>
                        </>
                      )}
                      
                      <Button
                        variant="ghost"
                        size="sm"
                        className="h-8 w-8 p-0 text-red-500 hover:text-red-700"
                        onClick={() => removeFile(uploadedFile.id)}
                      >
                        <X className="h-4 w-4" />
                      </Button>
                    </div>
                  </div>
                </div>
              </Card>
            ))}
          </div>
        </div>
      )}
    </div>
  )
}